package com.yeyks.newwebsocket;

import com.alibaba.fastjson.JSONObject;
import com.yeyks.base.Arguments;
import com.yeyks.config.MyApplicationContextAware;
import com.yeyks.service.WebSocketService;
import com.yeyks.util.Utility;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.net.InetSocketAddress;
import java.util.IdentityHashMap;
import java.util.Map;

/**
 * @Author fuchangshuai
 * @date 2019/4/3 5:25 PM
 */
@Component
@ServerEndpoint(value = "/webSocket/{userId}", configurator = MyApplicationContextAware.class)
@Slf4j
public class WebSocket {

    @Autowired
    private WebSocketService webSocketService;

    /**
     * 用户id
     */
    private String userId;

    private static final String connect_type = "连接成功";

    private static final String out_type = "断开连接";

    /**
     * 建立连接
     */
    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) {
        try {
            InetSocketAddress remoteAddress = WebsocketIp.getRemoteAddress(session);
            log.info("websocket客户端链接ip{}", remoteAddress);
            if (Arguments.notEmpty(userId) && !"null".equals(userId) && !"NULL".equals(userId)) {
//                log.info("现在连接的客户id：" + session.getId() + "用户id为：" + userId);
                this.userId = userId;
                WebSocketUtils.add(userId, session);
                webSocketService.insertSelective(Integer.parseInt(userId), session.getId(), connect_type);
            }
        } catch (Exception e) {
            log.info("错误信息{}", e.getLocalizedMessage());
            WebSocketUtils.remove(userId, session.getId());
        }

    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.info("服务端发生了错误" + error.getMessage());
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose(Session session) {
        WebSocketUtils.remove(userId, session.getId());
        webSocketService.insertSelective(Integer.parseInt(userId), session.getId(), out_type);
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session) {
//        log.info("来自客户端消息：" + message + "客户端的id是：" + session.getId());
        session.getAsyncRemote().sendText(message);
    }


    /**
     * 给指定用户推消息
     *
     * @param message
     * @param toUserId
     */
    public void sendMessageTo(Object message, String toUserId) {
        Map<String, Session> clients = WebSocketUtils.clients;
        for (Map.Entry<String, Session> entry : clients.entrySet()) {
            if (entry.getKey().equals(toUserId)) {
                entry.getValue().getAsyncRemote().sendText(JSONObject.toJSONString(message));
            }
        }
    }

    /**
     * 给指定用户推消息(同一个人多地登陆都推消息)
     *
     * @param message
     * @param toUserId
     */
    public void sendMessageToMore(String message, String toUserId) {
        Map<String, IdentityHashMap<String, Session>> map = WebSocketUtils.clientsAll2;
        //Map<String, Map<String, Session>>
        for (Map.Entry<String, IdentityHashMap<String, Session>> mapEntry : map.entrySet()) {
            if (mapEntry.getValue() != null) {
                //Map<String, Session>
                for (Map.Entry<String, Session> entry : mapEntry.getValue().entrySet()) {
                    if (entry.getKey() != null && toUserId.equals(entry.getKey())) {
                        if (entry.getValue() != null) {
                            try {
                                entry.getValue().getAsyncRemote().sendText(message);
                            } catch (Exception e) {
//                                log.info("推送异常{}，在线用户id{}，将要推送用户id{}", e.getLocalizedMessage(), JSONObject.toJSONString(mapEntry.getValue().keySet()), toUserId);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 给所有用户推消息
     *
     * @param message
     * @param fromUserId
     */
    public void sendMessageAll(Object message, String fromUserId) {
        Map<String, Session> clients = WebSocketUtils.clients;
        for (Map.Entry<String, Session> entry : clients.entrySet()) {
            entry.getValue().getAsyncRemote().sendText(JSONObject.toJSONString(message));
        }
    }

    /**
     * 获取在线人数
     *
     * @return
     */
    public static synchronized int getOnlineCount() {
        return WebSocketUtils.onlineNumber;
    }
}
